/**
 * 错误处理统一化初始化器
 * 在项目启动时集成统一的错误处理和日志系统
 */

import { GlobalErrorHandler, ErrorHandlerConfig } from './GlobalErrorHandler';
import { UnifiedLogger, LogLevel } from '../logging/UnifiedLogger';
import { GameError, ErrorFactory } from './ErrorTypes';

/**
 * 错误处理系统配置
 */
export interface ErrorSystemConfig {
    /** 全局错误处理配置 */
    errorHandler?: ErrorHandlerConfig;
    /** 日志系统配置 */
    logging?: {
        /** 日志级别 */
        level?: LogLevel;
        /** 是否启用文件日志 */
        enableFileLogging?: boolean;
        /** 日志文件路径 */
        logFilePath?: string;
        /** 默认服务上下文 */
        defaultContext?: {
            service?: string;
            version?: string;
            environment?: string;
        };
    };
    /** 错误通知配置 */
    notifications?: {
        /** 是否启用错误通知 */
        enabled: boolean;
        /** 通知渠道配置 */
        channels?: {
            /** 控制台通知 */
            console?: boolean;
            /** 文件通知 */
            file?: boolean;
            /** 自定义通知回调 */
            custom?: (error: GameError) => void;
        };
    };
}

/**
 * 错误处理统一化管理器
 */
export class ErrorHandlingUnification {
    private static isInitialized = false;
    private static globalErrorHandler: GlobalErrorHandler;
    private static unifiedLogger: UnifiedLogger;
    private static config: ErrorSystemConfig;

    /**
     * 初始化统一错误处理系统
     */
    static async initialize(config: ErrorSystemConfig = {}): Promise<void> {
        if (this.isInitialized) {
            console.warn('Error handling system already initialized');
            return;
        }

        console.log('🚨 Initializing Unified Error Handling System...');
        
        try {
            this.config = this.mergeConfig(config);
            
            // 第一步：初始化日志系统
            await this.initializeLogging();
            
            // 第二步：初始化全局错误处理器
            await this.initializeErrorHandler();
            
            // 第三步：设置错误通知
            await this.setupErrorNotifications();
            
            // 第四步：注册全局处理器
            this.registerGlobalHandlers();
            
            this.isInitialized = true;
            this.unifiedLogger.info('Unified error handling system initialized successfully', {
                service: 'ErrorHandlingUnification'
            });
            
        } catch (error) {
            console.error('❌ Failed to initialize error handling system:', error);
            throw error;
        }
    }

    /**
     * 合并配置
     */
    private static mergeConfig(userConfig: ErrorSystemConfig): ErrorSystemConfig {
        const defaultConfig: ErrorSystemConfig = {
            errorHandler: {
                hideStackInProduction: true,
                logAllErrors: true,
                notifications: {
                    enabled: true,
                    threshold: LogLevel.ERROR
                },
                metrics: {
                    enabled: true,
                    windowSize: 60
                }
            },
            logging: {
                level: process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.DEBUG,
                enableFileLogging: process.env.NODE_ENV === 'production',
                logFilePath: 'logs/error.log',
                defaultContext: {
                    service: 'GameServer',
                    version: process.env.npm_package_version || '1.0.0',
                    environment: process.env.NODE_ENV || 'development'
                }
            },
            notifications: {
                enabled: true,
                channels: {
                    console: true,
                    file: process.env.NODE_ENV === 'production'
                }
            }
        };

        return {
            errorHandler: { ...defaultConfig.errorHandler, ...userConfig.errorHandler },
            logging: { ...defaultConfig.logging, ...userConfig.logging },
            notifications: { ...defaultConfig.notifications, ...userConfig.notifications }
        };
    }

    /**
     * 初始化日志系统
     */
    private static async initializeLogging(): Promise<void> {
        this.unifiedLogger = UnifiedLogger.getInstance();
        
        // 设置日志级别
        if (this.config.logging?.level) {
            this.unifiedLogger.setLevel(this.config.logging.level);
        }
        
        // 设置默认上下文
        if (this.config.logging?.defaultContext) {
            this.unifiedLogger.setDefaultContext(this.config.logging.defaultContext);
        }
        
        // 如果启用文件日志，添加文件输出器
        if (this.config.logging?.enableFileLogging) {
            const { FileAppender } = await import('../logging/UnifiedLogger');
            const fileAppender = new FileAppender(this.config.logging.logFilePath);
            this.unifiedLogger.addAppender(fileAppender);
        }
        
        this.unifiedLogger.info('Logging system initialized', {
            service: 'ErrorHandlingUnification',
            metadata: {
                level: this.config.logging?.level,
                fileLogging: this.config.logging?.enableFileLogging
            }
        });
    }

    /**
     * 初始化全局错误处理器
     */
    private static async initializeErrorHandler(): Promise<void> {
        this.globalErrorHandler = GlobalErrorHandler.getInstance(this.config.errorHandler);
        this.globalErrorHandler.initialize();
        
        this.unifiedLogger.info('Global error handler initialized', {
            service: 'ErrorHandlingUnification'
        });
    }

    /**
     * 设置错误通知
     */
    private static async setupErrorNotifications(): Promise<void> {
        if (!this.config.notifications?.enabled) {
            return;
        }

        const channels = this.config.notifications.channels;
        
        // 设置错误通知回调
        const notificationCallback = (error: GameError) => {
            // 控制台通知
            if (channels?.console) {
                console.error(`🚨 Error Notification: [${error.code}] ${error.userMessage}`);
                if (process.env.NODE_ENV !== 'production') {
                    console.error('Error details:', error.toJSON());
                }
            }
            
            // 文件通知
            if (channels?.file) {
                this.unifiedLogger.error('Error notification', {
                    service: 'ErrorNotification'
                }, error.toJSON());
            }
            
            // 自定义通知
            if (channels?.custom) {
                try {
                    channels.custom(error);
                } catch (customError) {
                    this.unifiedLogger.error('Custom error notification failed', {
                        service: 'ErrorHandlingUnification'
                    }, { customError, originalError: error.toJSON() });
                }
            }
        };

        // 更新错误处理器配置
        if (this.config.errorHandler?.notifications) {
            this.config.errorHandler.notifications.callback = notificationCallback;
        }
        
        this.unifiedLogger.info('Error notifications configured', {
            service: 'ErrorHandlingUnification',
            metadata: { channels }
        });
    }

    /**
     * 注册全局处理器
     */
    private static registerGlobalHandlers(): void {
        // 为现有的console方法添加拦截（在开发环境）
        if (process.env.NODE_ENV !== 'production') {
            this.interceptConsoleErrors();
        }
        
        // 定期生成错误报告
        setInterval(() => {
            this.generatePeriodicErrorReport();
        }, 60 * 60 * 1000); // 每小时生成一次报告
        
        this.unifiedLogger.info('Global error handlers registered', {
            service: 'ErrorHandlingUnification'
        });
    }

    /**
     * 拦截控制台错误（开发环境）
     */
    private static interceptConsoleErrors(): void {
        const originalConsoleError = console.error;
        const originalConsoleWarn = console.warn;
        
        console.error = (...args: any[]) => {
            // 如果参数中包含Error对象，转换为GameError
            const hasError = args.some(arg => arg instanceof Error);
            if (hasError) {
                const error = args.find(arg => arg instanceof Error);
                const gameError = ErrorFactory.serviceUnavailable('Console Error', {
                    metadata: { consoleArgs: args }
                });
                this.globalErrorHandler.handleServiceError(gameError, 'Console');
            }
            
            // 调用原始方法
            originalConsoleError.apply(console, args);
        };
        
        console.warn = (...args: any[]) => {
            this.unifiedLogger.warn('Console warning', {
                service: 'Console'
            }, { args });
            
            // 调用原始方法
            originalConsoleWarn.apply(console, args);
        };
    }

    /**
     * 生成定期错误报告
     */
    private static generatePeriodicErrorReport(): void {
        try {
            const report = this.globalErrorHandler.generateErrorReport();
            
            if (report.totalErrors > 0) {
                this.unifiedLogger.info('Periodic error report', {
                    service: 'ErrorHandlingUnification'
                }, report);
                
                // 如果错误数量过多，发出警告
                if (report.totalErrors > 100) {
                    this.unifiedLogger.warn('High error count detected', {
                        service: 'ErrorHandlingUnification'
                    }, { totalErrors: report.totalErrors });
                }
            }
        } catch (error) {
            this.unifiedLogger.error('Failed to generate error report', {
                service: 'ErrorHandlingUnification'
            }, { error });
        }
    }

    /**
     * 获取错误处理器实例
     */
    static getErrorHandler(): GlobalErrorHandler {
        if (!this.isInitialized) {
            throw new Error('Error handling system not initialized');
        }
        return this.globalErrorHandler;
    }

    /**
     * 获取日志记录器实例
     */
    static getLogger(): UnifiedLogger {
        if (!this.isInitialized) {
            throw new Error('Error handling system not initialized');
        }
        return this.unifiedLogger;
    }

    /**
     * 创建服务专用的错误处理工具
     */
    static createServiceErrorHandler(serviceName: string) {
        const errorHandler = this.getErrorHandler();
        const logger = this.getLogger();
        
        return {
            /**
             * 处理服务错误
             */
            handleError: (error: any, methodName?: string) => {
                return errorHandler.handleServiceError(error, serviceName, methodName);
            },
            
            /**
             * 处理API错误
             */
            handleApiError: (error: any, requestId?: string) => {
                return errorHandler.handleApiError(error, requestId);
            },
            
            /**
             * 创建成功响应
             */
            createSuccess: <T>(data: T, requestId?: string) => {
                return errorHandler.createSuccessResponse(data, requestId);
            },
            
            /**
             * 记录日志
             */
            log: {
                info: (message: string, data?: any) => logger.info(message, { service: serviceName }, data),
                warn: (message: string, data?: any) => logger.warn(message, { service: serviceName }, data),
                error: (message: string, error?: Error, data?: any) => logger.error(message, { service: serviceName }, data, error),
                debug: (message: string, data?: any) => logger.debug(message, { service: serviceName }, data)
            }
        };
    }

    /**
     * 获取系统状态
     */
    static getSystemStatus(): {
        initialized: boolean;
        errorMetrics: any;
        config: ErrorSystemConfig;
    } {
        return {
            initialized: this.isInitialized,
            errorMetrics: this.isInitialized ? this.globalErrorHandler.generateErrorReport() : null,
            config: this.config
        };
    }

    /**
     * 重置错误统计
     */
    static resetErrorMetrics(): void {
        if (this.isInitialized) {
            this.globalErrorHandler.resetMetrics();
            this.unifiedLogger.info('Error metrics reset', {
                service: 'ErrorHandlingUnification'
            });
        }
    }

    /**
     * 优雅关闭
     */
    static async shutdown(): Promise<void> {
        if (!this.isInitialized) {
            return;
        }

        this.unifiedLogger.info('Shutting down error handling system', {
            service: 'ErrorHandlingUnification'
        });

        // 生成最终错误报告
        const finalReport = this.globalErrorHandler.generateErrorReport();
        this.unifiedLogger.info('Final error report', {
            service: 'ErrorHandlingUnification'
        }, finalReport);

        // 清理日志记录器
        this.unifiedLogger.dispose();
        
        this.isInitialized = false;
    }
}

/**
 * 便捷的初始化函数
 */
export async function initializeUnifiedErrorHandling(config?: ErrorSystemConfig): Promise<void> {
    await ErrorHandlingUnification.initialize(config);
}

/**
 * 导出便捷的工厂函数
 */
export function createServiceErrorHandler(serviceName: string) {
    return ErrorHandlingUnification.createServiceErrorHandler(serviceName);
}

/**
 * 导出常用错误工厂
 */
export { ErrorFactory, GameError } from './ErrorTypes';

/**
 * 导出装饰器
 */
export { HandleErrors, HandleApiErrors } from './GlobalErrorHandler';
